import re
import json
from datetime import datetime

from django import http
from django.views import View
from django.db.models import Q
from django.db import transaction

from .models import Order
from homes.models import House
from ihome.utils.views import LoginRequiredJSONMixin
from ihome.utils import statusCode
from ihome.utils.logger import logger


class OrderView(LoginRequiredJSONMixin, View):

    def post(self, request):
        """创建订单接口"""

        json_data = json.loads(request.body.decode())
        house_id = json_data.get("house_id")

        start_date = json_data.get("start_date")
        end_date = json_data.get("end_date")

        start_time = datetime.strptime(start_date, '%Y-%m-%d')
        end_time = datetime.strptime(end_date, '%Y-%m-%d')

        delata = end_time - start_time
        days = delata.days

        now_time = datetime.now()

        user = request.user

        try:
            house = House.objects.get(pk=house_id, is_active=True)
            old_house_order_count = house.order_count
        except Exception as e:
            return http.JsonResponse({"errno": statusCode.PARAMERR, "errmsg": "该房源已下架"})

        if not all([house_id, start_date, end_date]):
            return http.JsonResponse({"errno": statusCode.PARAMERR, "errmsg": "参数错误"})

        if (start_time.date() < now_time.date()) or (end_time.date() < start_time.date()):
            return http.JsonResponse({"errno": statusCode.PARAMERR, "errmsg": "参数错误"})

        if user.id == house.user.id:
            return http.JsonResponse({"errno": statusCode.ROLEERR, "errmsg": "用户身份错误"})

        if not (house.min_days <= days <= house.max_days):
            return http.JsonResponse({"errno": statusCode.PARAMERR, "errmsg": f"最少入住天数：{house.min_days}，最大入住天数：{house.max_days}"})

        try:
            # TODO：忽略已拒单订单，查询用户预定时间段是否已有订单，result不为空 --> 是
            result = house.order_set.exclude(status=Order.ORDER_STATUS['REJECTED']).filter(Q(end_date__gt=start_time) | Q(begin_date__gt=end_time))
        except Exception as e:
            logger.info('数据查询错误', e)
            return http.JsonResponse({"errno": statusCode.DBERR, "errmsg": "数据库查询错误"})

        if result:
            return http.JsonResponse({"errno": statusCode.DATAEXIST, "errmsg": "该房间已有预定"})

        with transaction.atomic():  # TODO: 创建事务
            save_id = transaction.savepoint()  # 保存点

            try:
                order = Order.objects.create(
                    user=user,
                    house=house,
                    begin_date=start_time,
                    end_date=end_time,
                    days=days,
                    house_price=house.price,
                    amount=int(house.price) * int(days),
                    status=Order.ORDER_STATUS.get('WAIT_ACCEPT')
                )

                # 判断该是否被抢单
                _result = House.objects.filter(pk=house_id, order_count=old_house_order_count).update(
                    order_count=old_house_order_count+1
                )

                if _result == 0:
                    transaction.savepoint_rollback(save_id)  # 回滚数据
                    return http.JsonResponse({"errno": statusCode.DATAEXIST, "errmsg": "该房源已被预定"})

            except Exception as e:
                transaction.savepoint_rollback(save_id)  # 回滚数据
                logger.info('数据查询错误', e)
                return http.JsonResponse({"errno": statusCode.DBERR, "errmsg": "数据库查询错误"})

        return http.JsonResponse({
            "errno": statusCode.OK,
            "errmsg": "下单成功",
            "data": {
                'order_id': order.id
            }
        })

    def get(self, request):
        """获取订单列表"""

        role = request.GET.get("role")
        user = request.user

        if not role:
            return http.JsonResponse({"errno": "4103", "errmsg": "PARAMERR"})

        if not role in ('custom', 'landlord'):
            return http.JsonResponse({"errno": "4103", "errmsg": "PARAMERR"})

        order_list = []
        my_orders = []

        # 用户订单
        if role == 'custom':
            my_orders = user.orders.all()
        elif role == 'landlord':
            try:
                my_houses = user.houses.all()
            except Exception as e:
                logger.info('数据查询错误', e)
                return http.JsonResponse({"errno": statusCode.DBERR, "errmsg": "数据库查询错误"})

            for house in my_houses:
                orders = house.order_set.all()
                for order in orders:
                    my_orders.append(order)

        for order in my_orders:
            order_list.append({
                "amount": order.amount,
                "comment": order.comment,
                "ctime": order.create_time.date(),
                "days": order.days,
                "end_date": order.end_date,
                "img_url": order.house.index_image_url.url,
                "order_id": order.id,
                "start_date": order.begin_date,
                "status": Order.ORDER_STATUS_ENUM.get(order.status),
                "title": order.house.title
            })

        return http.JsonResponse({
            "data": {
                'orders': order_list,
            },
            "errno": "0",
            "errmsg": "OK",
        })


class AcceptOrReject(LoginRequiredJSONMixin, View):
    """接单、拒单"""

    def put(self, request, order_id):
        json_data = json.loads(request.body.decode())

        action = json_data.get("action")
        reason = json_data.get("reason")

        if not action:
            return http.JsonResponse({"errno": statusCode.PARAMERR, "errmsg": "参数错误"})

        if action not in ("accept", "reject"):
            return http.JsonResponse({"errno": statusCode.PARAMERR, "errmsg": "参数错误"})

        try:
            order = Order.objects.get(pk=order_id)
        except Exception as e:
            logger.info('数据查询错误', e)
            return http.JsonResponse({"errno": statusCode.DBERR, "errmsg": "数据库查询错误"})

        if action == 'accept':
            order.status = Order.ORDER_STATUS.get('WAIT_COMMENT')
            order.save()
        elif action == 'reject':
            order.status = Order.ORDER_STATUS.get('REJECTED')
            order.comment = reason
            order.save()

        return http.JsonResponse({"errno": statusCode.OK, "errmsg": "操作成功"})


class CommentOrder(LoginRequiredJSONMixin, View):
    """评价订单"""

    def put(self, request, order_id):
        json_data = json.loads(request.body.decode())

        comment = json_data.get("comment")

        if not comment:
            return http.JsonResponse({"errno": "4103", "errmsg": "PARAMERR"})

        try:
            order = Order.objects.get(pk=order_id)
        except Exception as e:
            logger.info('数据查询错误', e)
            return http.JsonResponse({"errno": statusCode.DBERR, "errmsg": "数据库查询错误"})

        order.comment = comment
        order.status = Order.ORDER_STATUS.get('COMPLETE')
        order.save()
        return http.JsonResponse({"errno": statusCode.OK, "errmsg": "评论成功"})
